﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;

namespace AssemblyExplorer
{
    public partial class StrategyPage : UserControl
    {
        public event EventHandler PluginSelected;

        public Type PluginInterfaceType;
        private string _userProvidedCode;
        private IPlugin _plugin;
        private Assembly _assembly;

        public IPlugin Plugin { get { return _plugin; } }

        public StrategyPage()
        {
            InitializeComponent();
        }

        private string PluginState
        {
            get { return (_plugin == null ? String.Empty : _plugin.GetState()); }
            set 
            {
                if (_plugin != null)
                {
                    _plugin.LoadState(value);
                }
            }
        }

        public StrategySettings ProvidedSettings
        {
            get
            {
                StrategySettings settings = new StrategySettings();
                settings.StrategyOption = this.StrategyOption;
                settings.PluginAssembly = this.PluginAssembly;
                settings.PluginState = this.PluginState;
                settings.PluginType = this.PluginType;
                settings.UserProvidedCode = _userProvidedCode;
                return settings;
            }
        }

        public void LoadSettings(StrategySettings settings)
        {
            this.StrategyOption = settings.StrategyOption;
            this.PluginAssembly = settings.PluginAssembly;
            this.PluginType = settings.PluginType;
            this.PluginState = settings.PluginState;
            _userProvidedCode = settings.UserProvidedCode;
        }

        private StrategyOption StrategyOption
        {
            get
            {
                if (rbtDefault.Checked)
                    return StrategyOption.Default;
                else if (rbtPlugin.Checked)
                    return StrategyOption.Plugin;
                else if (rbtCode.Checked)
                    return StrategyOption.UserCode;
                else
                    throw new Exception();
            }
            set
            {
                switch (value)
                {
                    case StrategyOption.Default:
                        rbtDefault.Checked = true;
                        break;
                    case StrategyOption.Plugin:
                        rbtPlugin.Checked = true;
                        break;
                    case StrategyOption.UserCode:
                        rbtCode.Checked = true;
                        break;
                }
            }
        }

        private void btnChoosePlugin_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "Assembly files|*.dll;*.exe";
            if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                this.PluginAssembly = dlg.FileName;
            }
        }

        private string PluginAssembly
        {
            get { return txtPluginFile.Text; }
            set
            {
                if (value == null) return;
                try
                {
                    txtPluginFile.Text = value;
                    cbxPlugins.Items.Clear();
                    cbxPlugins.Items.AddRange(ReflectionHelper.GetTypesByInterface(
                        value, PluginInterfaceType));
                    _assembly = Assembly.LoadFrom(value);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        private string PluginType
        {
            get { return (cbxPlugins.SelectedItem == null ? String.Empty : cbxPlugins.SelectedItem.ToString()); }
            set
            {
                if (value == null) return;
                if (cbxPlugins.Items.Contains(value))
                {
                    cbxPlugins.SelectedIndex = cbxPlugins.Items.IndexOf(value);
                }
            }
        }

        private void btnEditCode_Click(object sender, EventArgs e)
        {
            frmCode frm = new frmCode();
            frm.Code = _userProvidedCode;
            if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                _userProvidedCode = frm.Code;
            }
        }

        private void cbxPlugins_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbxPlugins.SelectedIndex != -1 && _assembly != null)
            {
                try
                {
                    _plugin = (IPlugin)_assembly.CreateInstance(cbxPlugins.SelectedItem.ToString());
                    if (PluginSelected != null) PluginSelected(this, EventArgs.Empty);
                }
                catch (Exception ex)
                {
                    _plugin = null;
                    MessageBox.Show(ex.Message);
                }
            }
        }

    }
}
